#ifndef OPADD
#define OPADD

#include "AWScript.hpp"

//Operation +
//formula:
//

cText TEXT_ADDOVERLOAD = "ADDOVERLOAD";

//preLining:
//void funOpAddPreL(SetIdentity* what){
//	//fPreL_seb(what);
//};

//PostLining:
void funOpAddPostL(ptrText code, ptrIdentity what){
	//	what->Extended=(void*)(new cText(code,what->Range));
};

//MkTree:
ptrParsedElement funOpAddMkTree(ptrText code, ptrIdentity identity, ptrParsedElement PE){
	PE->Extended=identity->Extended;
	return PE;
};

//Evaluate:
sRecord funOpAddEva(ptrRETNode retnode, ptrParsedElement pe, void* scope){
	sRecord adder=pe->SubElements[0]->Operation->onEvaluate(retnode, pe->SubElements[0],scope);
	sRecord addee=pe->SubElements[1]->Operation->onEvaluate(retnode, pe->SubElements[1],scope);
	ptrRecord overload=(adder.dough->Statics->search(TEXT_ADDOVERLOAD)); //it returns if var not found
	//if overloaded:
	if (overload){
		ptrRETNode	nRET=retnode->Append(overload->dough);
		//init this that:
		nRET->Locals.push(TEXT_THIS,*overload);
		nRET->Locals.push(TEXT_THAT,adder);
		//init addee as param
		paramInit(nRET,retnode,overload->dough,pe);
		//Execute!:
		try{
			return adder.dough->ParsedTree->Operation->onEvaluate(nRET,adder.dough->ParsedTree,NULL);
		}
		catch (sRecord &ret){
			return ret;
		};
	}
	else{
		//for test
		return sRecord(CreateNumberDough(new Number(getNumber(adder.dough) + getNumber(addee.dough))));
		/*to be used
		//Default Addition:N+T,T+T,N+N,else.
		SysText *AdderType=adder.dough->Extended.search(TEXT_TYPE),
				*AddeeType=addee.dough->Extended.search(TEXT_TYPE);     //there should always be a type.
		funAddition fun=Addition.search(*AdderType,*AddeeType);   //find the target Addition Function
		return fun?fun(adder,addee):NULL;                         //if exist a addition function, use it.
		*/
		/*
		if (*AdderType==TEXT_NUMBER){
			if (*AddeeType==TEXT_NUMBER){
				/*
				ptrDough Result=CreateDough();
				Result->Extended.push(TEXT_TYPE,TEXT_NUMBER);
				Result->Extended.push(TEXT_TYPEVALUE,
					(void*)(new double( //directly new a cNumber from addition, instead of calculate then copy from stack->pile
						(double)*(adder->Extended.search(TEXT_TYPEVALUE))
						+
						(double)*(adder->Extended.search(TEXT_TYPEVALUE))
					))
				);
				*\/
				return CreateNumberDough(
					NewAddedNumber(
						*(ptrNumber)(adder->Extended.search(TEXT_TYPEVALUE))
						+
						*(ptrNumber)(addee->Extended.search(TEXT_TYPEVALUE))
					)
				);
			}
			else if(*AddeeType==TEXT_TEXT){
				ptrText tmp=cText(*(ptrNumber)(adder->Extended.search(TEXT_TYPEVALUE)));
				tmp+=*(ptrText)(addee->Extended.search(TEXT_TYPEVALUE));
				return CreateTextDough(tmp);
			};
		}
		else if(*AdderType==TEXT_TEXT){
			if(*AddeeType==TEXT_NUMBER){
				ptrText tmp=cText(*(ptrNumber)(adder->Extended.search(TEXT_TYPEVALUE)));
				tmp+=*(ptrNumber)(addee->Extended.search(TEXT_TYPEVALUE));
				return CreateTextDough(tmp);
			}
			else if(*AddeeType==TEXT_TEXT){
				ptrText tmp=cText(*(ptrNumber)(adder->Extended.search(TEXT_TYPEVALUE)));
				tmp+=*(ptrText)(addee->Extended.search(TEXT_TYPEVALUE));
				return CreateTextDough(tmp);
			};
		};
		*/

	}
}

ptrOperation loadOpAdd(){
	ptrOperation tmp=new cOperation();
	tmp->Name="add";
	tmp->onEvaluate=funOpAddEva;
	tmp->onMakingTree=funOpAddMkTree;
	tmp->onPostLining=funOpAddPostL;
	//tmp->onPreLining=funOpAddPreL;
	return tmp;
}

#endif